package com.quick.develop.flowable.framework.cmd.admin;

import org.flowable.common.engine.impl.interceptor.Command;
import org.flowable.common.engine.impl.interceptor.CommandContext;
import org.flowable.engine.HistoryService;
import org.flowable.engine.history.HistoricProcessInstance;
import org.flowable.engine.impl.cfg.ProcessEngineConfigurationImpl;
import org.flowable.engine.impl.persistence.entity.HistoricProcessInstanceEntity;
import org.flowable.engine.impl.util.CommandContextUtil;

import java.io.Serializable;
import java.util.Objects;

import static com.quick.develop.flowable.enums.BpmErrorCodeConstants.PROCESS_DELETE_FAIL_MAIN_INSTANCE_NOT_EXISTS;
import static com.quick.develop.framework.common.utils.ServiceExceptionUtils.exception;

/**
 * @author junyuan.liu
 * @description:
 * @date 2022/9/14 10:50
 */
public class DeleteProcessCascadeCmd implements Command<Void>, Serializable {
    private static final long serialVersionUID = -4764260110838358894L;

    protected String processInstanceId;
    protected String businessKey;
    protected boolean finished;
    protected String mainProInstId;
    
    public DeleteProcessCascadeCmd(String processInstanceId, String businessKey) {
        this.processInstanceId = processInstanceId;
        this.businessKey = businessKey;
    }

    @Override
    public Void execute(CommandContext commandContext) {
        ProcessEngineConfigurationImpl processEngineConfiguration = CommandContextUtil.getProcessEngineConfiguration(commandContext);
        HistoryService historyService = processEngineConfiguration.getHistoryService();
        // 获取到主流程
        HistoricProcessInstance mainInstance = historyService.createHistoricProcessInstanceQuery()
                .processInstanceBusinessKey(businessKey)
                .excludeSubprocesses(true)
                .singleResult();
        if (Objects.isNull(mainInstance)) {
            throw exception(PROCESS_DELETE_FAIL_MAIN_INSTANCE_NOT_EXISTS);
        }
        this.mainProInstId = mainInstance.getId();
        // 主流程是否结束
        this.finished = historyService.createHistoricProcessInstanceQuery().finished()
                .processInstanceId(mainInstance.getId()).count() > 0;
        deleteInstance(commandContext);
        

        return null;
    }
    
    private void deleteInstance(CommandContext commandContext) {
        if (this.finished) {
            HistoricProcessInstanceEntity entity = CommandContextUtil.getHistoricProcessInstanceEntityManager(commandContext).findById(mainProInstId);
            CommandContextUtil.getHistoryManager(commandContext).recordProcessInstanceDeleted(mainProInstId, entity.getProcessDefinitionId(), null);
        }else {
            CommandContextUtil.getExecutionEntityManager(commandContext).deleteProcessInstance(mainProInstId, null, true, true);

        }
    }
}
